<?php
/**
 * Copyright (c) 2006-2008, Julien PORTALIER
 * http://featherphp.googlecode.com/
 * 
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 */

class Resampler
{
	protected $filename;
	public    $size;
	
	function __construct($filename=null)
	{
		if ($filename !== null) {
			$this->load($filename);
		}
	}
	
	/**
	 * Loads an image.
	 * 
	 * @param $filename String Path to image file.
	 */
	function load($filename)
	{
		if (!file_exists($filename)) {
			return false;
		}
		$this->size     = getimagesize($filename);
		$this->filename = $filename;
	}
	
	function __destruct()
	{
		$this->destroy();
	}
	
	function __get($attr)
	{
		if ($attr == 'image')
		{
			switch ($this->size['mime'])
			{
				case 'image/jpeg': $this->image =& imagecreatefromjpeg($this->filename); break;
				case 'image/png':  $this->image =& imagecreatefrompng($this->filename);  break;
				case 'image/gif':  $this->image =& imagecreatefromgif($this->filename);  break;
				default: return false;
			}
			return $this->image;
		}
		return false;
	}
	
	protected function destroy()
	{
		if ($this->image) {
			imagedestroy($this->image);
		}
		$this->size = null;
	}
	
	function rotate($degrees)
	{
		imagerotate($this->image, $degrees, 0);
	}
	
	function flip($direction)
	{
		$w = $this->size[0];
		$h = $this->size[1];
		$dest_img = imagecreatetruecolor($w, $h);
		
		for ($x=0; $x < $width; $x++)
		{
			for ($y=0 ; $y<$height ; $y++)
			{
				if ($type == MIRROR_HORIZONTAL) {
					imagecopy($dest_img, $this->image, $w - $x - 1, $y, $x, $y, 1, 1);
				}
				if ($type == MIRROR_VERTICAL) {
					imagecopy($dest_img, $this->image, $x, $h - $y - 1, $x, $y, 1, 1);
				}
				if ($type == MIRROR_BOTH) {
					imagecopy($dest_img, $this->image, $w - $x - 1, $h - $y -1, $x, $y, 1, 1);
				}
			}
		}
		
		imagedestroy($this->image);
		$this->image = $dest_img;
	}
	
	/**
	 * @todo Crop doesn't work as expected if $max_w != $max_h (non square)
	 * 
	 * @return Boolean
	 * @param $dest_file String
	 * @param $max_w  Integer[optional]
	 * @param $max_h  Integer[optional]
	 * @param $crop   Boolean[optional]
	 * @param $rotate Mixed[optional] Can be false or rotation's degree.
	 * @param $flip   Mixed[optional] Can be false, 'vert' or 'horiz'.
	 */
	function create($dest_file, $max_w=100, $max_h=100, $crop=false)
	{
		if (!$this->image) {
			return false;
		}
		$src_w = $this->size[0];
		$src_h = $this->size[1];
		$src_x = 0;
		$src_y = 0;
		
		if (!$crop)
		{
			# resampled with aspect ratio
			if ($src_w > $src_h)
			{
				$dest_w = $max_w;
				$dest_h = round($src_h / $src_w * $dest_w);
				if ($dest_h > $max_h)
				{
					$dest_h = $max_h;
					$dest_w = round($src_w / $src_h * $dest_h);
				}
			}
			elseif ($src_w < $src_h)
			{
				$dest_h = $max_h;
				$dest_w = round($src_w / $src_h * $dest_h);
				if ($dest_w > $max_w)
				{
					$dest_w = $max_w;
					$dest_h = round($src_h / $src_w * $dest_w);
				}
			}
			else
			{
				$dest_w = ($max_w > $max_h) ? $max_h : $max_w;
				$dest_h = $dest_w;
			}
		}
		else
		{
			# resampled with cropping
			$dest_w = $max_w;
			$dest_h = $max_h;
			if ($src_w > $src_h)
			{
				$src_x = round(($src_w - $src_h) / 2);
				$src_y = 0;
				$src_w = $src_h;
			}
			elseif ($src_w < $src_h)
			{
				$src_x = 0;
				$src_y = round(($src_h - $src_w) / 2);
				$src_h = $src_w;
			}
		}
		
		# generates a resampled image
		$dest_img = imagecreatetruecolor($dest_w, $dest_h);
		
		if (function_exists('imagecopyresampled'))
		{
			if (!imagecopyresampled($dest_img, $this->image, 0, 0, $src_x, $src_y, $dest_w, $dest_h, $src_w, $src_h)) {
				throw new Exception(t('An error occured while resampling image.', 'global.file'));
			}
		}
		else
		{
			if (!imagecopyresized($dest_img, $this->image, 0, 0, $src_x, $src_y, $dest_w, $dest_h, $src_w, $src_h)) {
				throw new Exception(t('An error occured while resizing image.', 'global.file'));
			}
		}
		
		# saves resampled image to jpeg (with quality 95)
		imagejpeg($dest_img, $dest_file, 95);
		imagedestroy($dest_img);
		
		return true;
	}
	
	function save($filename=null)
	{
		# saves image to jpeg (with quality 95)
		imagejpeg($this->image, $filename ? $filename : $this->filename, 95);
	}
}
?>